package com.bidevalution.business.impl;

import com.bidevalution.business.context.StepStage;
import com.bidevalution.business.exception.CheckException;
import com.bidevalution.business.exception.VoteException;
import com.bidevalution.business.factory.CheckJobBase;
import com.bidevalution.business.service.*;
import com.bidevalution.business.vote.service.BeAutoVoteConfigService;
import com.bidevalution.business.vote.vi.AutoVoteJobVi;
import com.bidevalution.business.vote.vi.CallStepJobVi;
import com.bidevalution.dao.entity.*;
import com.bidevalution.dao.enums.*;
import com.bidevalution.dao.mapper.BeSectionExpertProgressMapper;
import com.bidevalution.dao.mapper.BeSectionInfoMapper;
import com.bidevalution.service.layout.LayoutCode;
import com.bidevalution.support.context.Constants;

import com.bidevalution.support.context.ResponseObject;
import com.bidevalution.support.context.WebSocketOpTypeEnum;
import com.bidevalution.support.factory.WebSocketService;
import com.bidevalution.support.websocket.WebSocketCached;
import com.qtp.core.util.DateUtil;
import com.qtp.core.util.GsonUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import com.bidevalution.business.context.StepStage;
import com.bidevalution.dao.entity.CheckJob;
import com.bidevalution.dao.enums.CheckMsgTypeEnum;
import com.bidevalution.service.layout.LayoutCode;
import com.bidevalution.support.context.Constants;

import com.qtp.core.util.DateUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import com.bidevalution.business.context.StepStage;

import com.bidevalution.business.factory.StepJobFactory;
import com.bidevalution.business.factory.StepJobJdbcFactory;
import com.bidevalution.dao.entity.CheckJob;
import com.bidevalution.dao.enums.CheckMsgTypeEnum;
import com.bidevalution.dao.entity.CheckJob;
import com.bidevalution.dao.enums.CheckMsgTypeEnum;
import com.bidevalution.dao.mapper.BeSectionStepJobMapper;
import com.bidevalution.dao.mapper.BeSectionStepMapper;
import com.bidevalution.service.layout.LayoutCode;
import com.bidevalution.support.context.Constants;
import com.google.common.collect.Maps;
import com.qtp.core.util.DateUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.Map.Entry;

@Service
public class BeSectionStepJobServiceImpl implements BeSectionStepJobService {
	@Autowired
	private BeSectionStepJobMapper beSectionStepJobMapper;
	private Logger log = Logger.getLogger(getClass());
	@Autowired
	private BeSectionStepMapper beSectionStepMapper;
	@Autowired
	private JdbcTemplateService jdbcTemplateService;
	private Map<String, Object> sectionStepMap = Maps.newConcurrentMap();
	private List<BeSectionStepJob> unionSectionStepJobList;
	@Autowired
	private BeSectionParameterService beSectionParameterService;
	@Autowired
	private WebSocketService webSocketService;
	@Autowired
	private BeSectionExpertProgressService beSectionExpertProgressService;
	@Autowired
	private BeAutoVoteConfigService beAutoVoteConfigService;
	@Autowired
	private BeSectionExpertInfoService beSectionExpertInfoService;
	@Autowired
	private BeSectionExpertProgressMapper beSectionExpertProgressMapper;

	@Autowired
	private BeSectionInfoMapper beSectionInfoMapper;

	/**
	 * 评审过程调用事件 sectionStepId: stage:0，环节未评审之前触发，1:环节评审完成之后触发,2:执行中
	 *
	 * /** 递归调用，获取所有子节点关联的计算任务 @param @param childSectionStepJobMap @param @param
	 * sortNum @param @param stepCode @param @param param @param @return 参数 @return
	 * List<BeSectionStep> 返回类型 @throws
	 */
	public List<BeSectionStep> selectChildList(Map<Integer, List<BeSectionStepJob>> childSectionStepJobMap,
											   Integer sortNum, String stepCode, BeSectionStepJob param) {
		List<BeSectionStep> returnList = new LinkedList<BeSectionStep>();
		List<BeSectionStepJob> sectionStepJobList = new LinkedList<BeSectionStepJob>();
		for (BeSectionStep sectionStep : beSectionStepMapper.getChildSectionStepList(param.getSectionId(), stepCode)) {
			param.setSectionStepId(sectionStep.getSeqId());
			sectionStepJobList.addAll(beSectionStepJobMapper.selectUnFinishList(param));
			returnList.add(sectionStep);
			selectChildList(childSectionStepJobMap, new Integer(sortNum + 1), sectionStep.getStepCode(), param);
		}
		// 当前级别的所有任务
		unionSectionStepJobList = childSectionStepJobMap.get(sortNum);
		if (unionSectionStepJobList == null) {
			unionSectionStepJobList = new ArrayList<BeSectionStepJob>();
		}
		unionSectionStepJobList.addAll(sectionStepJobList);
		childSectionStepJobMap.put(sortNum, unionSectionStepJobList);
		return returnList;
	}

	@Override
	@Transactional
	public void updateStepJobByStepId(String sectionStepId, String status) throws Exception {
		BeSectionStepJob beSectionStepJob = new BeSectionStepJob();
		beSectionStepJob.setSectionStepId(sectionStepId);
		beSectionStepJob.setIsFinish(status);
		beSectionStepJob.setIsAdvanceExecute(Constants.TRUE);
		beSectionStepJobMapper.updateStepJobByStepId(beSectionStepJob);
	}


	@Transactional
	public void resetSubmitStepJobByStepId(String sectionStepId, String status) throws Exception {
		BeSectionStepJob beSectionStepJob = new BeSectionStepJob();
		beSectionStepJob.setSectionStepId(sectionStepId);
		beSectionStepJob.setIsFinish(status);
		beSectionStepJobMapper.resetSumitbJob(beSectionStepJob);
	}

	@Override
	public List<BeSectionStepJob> queryAdvanceExecuteJobToday() {
		return beSectionStepJobMapper.queryAdvanceExecuteJobToday();
	}

	@Transactional
	public void updateSectionStepJob(BeSectionStepJob beSectionStepJob) {
		beSectionStepJob.setIsFinish("1");
		beSectionStepJob.setUpdateTime(new Date());
		beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
	}

	@Override
	public List<BeSectionStepJob> selectListByStepId(String sectionStepId) {
		return beSectionStepJobMapper.selectListByStepId(sectionStepId);
	}

	/**
	 * 执行行任务，更新是否已经完成任务使用事务，只要有个没有完成则都不更新isFinish值
	 * <p>
	 * </p>
	 *
	 * @param submitCode      环节提交版本号
	 * @param stage           阶段
	 * @param expertId        专家id
	 * @param layoutCode      布局代码
	 * @return
	 * @throws Exception
	 * @see com.bidevalution.business.service.BeSectionStepJobService callRowJob(java.lang.String,
	 *      java.lang.String, java.lang.String, java.lang.String, java.lang.String,
	 *      java.lang.String, java.util.Map, java.util.List)
	 */
//	@Transactional
//	@Override
//	public void callRowJob(String sectionStepId, String submitCode, String expertId, String layouCode,
//			StepStage stepStage, Map<String, Object> rowData) throws Exception {
//		// 多线程执行任务
//		synchronized (this) {
//			if (sectionStepMap.get(sectionStepId) == null) {
//				sectionStepMap.put(sectionStepId, new Object());
//			}
//		}
//		Object object = sectionStepMap.get(sectionStepId);
//		synchronized (object) {
//			BeSectionStepJob param = new BeSectionStepJob();
//			param.setStage(stepStage.getCode());
//			param.setIsFinish(Constants.STR_NO);
//			param.setSectionStepId(sectionStepId);
//			List<BeSectionStepJob> sectionStepJobList = beSectionStepJobMapper.selectUnFinishList(param);
//			Object instanceObject;
//			StepRowJobFactory beforeStepRowJobFactory;
//			// 需要执行的任务数量
//			log.info("执行任务数量:" + sectionStepJobList.size());
//			long startTime;
//			try {
//				//标段参数
//				List<BeSectionParameter> beSectionParameterList = beSectionParameterService
//						.selectList(beSectionStepMapper.selectByPrimaryKey(sectionStepId).getSectionId());
//				for (BeSectionParameter beSectionParameter : beSectionParameterList) {
//					rowData.put("$PARAM_" + beSectionParameter.getParamId(), beSectionParameter.getParamValue());
//				}
//				//执行任务
//				for (BeSectionStepJob beSectionStepJob : sectionStepJobList) {
//					// 执行阶段 没有完成
//					if (!Constants.STATE_Y.equals(beSectionStepJob.getIsAdvanceExecute())) {
//						startTime = System.currentTimeMillis();
//
//						instanceObject = Class.forName(beSectionStepJob.getJobClass()).newInstance();
//						if (instanceObject instanceof StepRowJobFactory) {
//							log.info("开始执行任务:" + beSectionStepJob.getJobClass());
//							beforeStepRowJobFactory = (StepRowJobFactory) instanceObject;
//							if (!beforeStepRowJobFactory.execute(beSectionStepJob, submitCode, expertId, rowData)) {
//								log.error(beSectionStepJob.getJobClass() + ":" + beSectionStepJob.getJobContent()
//										+ ",任务执行失败");
//								throw new BizException(beSectionStepJob.getJobName() + "执行失败");
//							}
//							beSectionStepJob.setFinishCount(beSectionStepJob.getFinishCount() == null ? 1
//									: beSectionStepJob.getFinishCount() + 1);
//							beSectionStepJob.setUpdateTime(new Date());
//							beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
//							log.info("执行任务完成:" + beSectionStepJob.getJobClass() + ":耗时:"
//									+ (System.currentTimeMillis() - startTime));
//						}
//
//					}
//				}
//				for (BeSectionParameter beSectionParameter : beSectionParameterList) {
//					rowData.remove("$PARAM_" + beSectionParameter.getParamId());
//				}
//			} catch (Exception e) {
//				log.error(e.getMessage(), e);
//				throw e;
//			}
//		}
//
//	}

	@Transactional
	@Override
	public void callStepJob(BeSectionStep beSectionStep, String submitCode, StepStage stage, String expertId,
							String layoutCode) throws Exception {
		this.callStepJob(beSectionStep, submitCode, stage, expertId, layoutCode, false);
	}

	/**
	 * 评审过程调用事件 sectionStepId: stage:0，环节未评审之前触发，1:环节评审完成之后触发,2:执行中
	 *
	 * @throws Exception
	 */
	@Transactional
	@Override
	public void callStepJob(BeSectionStep beSectionStep, String submitCode, StepStage stage, String expertId,
							String layoutCode, boolean isConfirm) throws Exception {
		// 由于多线程执行的任务
		Object object = null;
		synchronized (this) {
			if (sectionStepMap.get(beSectionStep.getSeqId()) == null) {
				sectionStepMap.put(beSectionStep.getSeqId(), new Object());
			}
			object = sectionStepMap.get(beSectionStep.getSeqId());
		}
		synchronized (object) {
			BeSectionStepJob param = new BeSectionStepJob();
			param.setSectionStepId(beSectionStep.getSeqId());
			param.setStage(stage.getCode());
			param.setIsFinish(Constants.STR_NO);

			Map<String, Object> paramMap = Maps.newHashMap();
			for (BeSectionParameter beSectionParameter : beSectionParameterService
					.selectList(beSectionStep.getSectionId())) {
				paramMap.put("$PARAM_" + beSectionParameter.getParamId(), beSectionParameter.getParamValue());
			}
			List<BeSectionStepJob> sectionStepJobList = beSectionStepJobMapper.selectUnFinishList(param);
			// 需要执行的任务数量
			log.info(beSectionStep.getStepName()+",执行状态:"+stage.getCode()+"执行任务数量:" + sectionStepJobList.size());
			// 获取未完成的任务列表
			for (BeSectionStepJob beSectionStepJob : sectionStepJobList) {
				if (!Constants.STATE_Y.equals(beSectionStepJob.getIsAdvanceExecute())) {
					log.info(beSectionStep.getStepName()+"任务布局:"+beSectionStepJob.getLayoutCode()+",当前布局:"+layoutCode);
					if(!StringUtils.isEmpty(beSectionStepJob.getLayoutCode())) {
						//只执行对应的布局job
						if(beSectionStepJob.getLayoutCode().equals(layoutCode)) {
							executeJob(expertId, layoutCode, stage, submitCode, beSectionStepJob, paramMap, isConfirm);
						}else {
							log.error("任务layoutCode的值与当前环节不符合:"+beSectionStepJob.getLayoutCode());
						}
					}else{
						//兼容以前没有layoutcode的job
						executeJob(expertId, layoutCode, stage, submitCode, beSectionStepJob, paramMap, isConfirm);
					}

				}
			}
		}
	}

	@Override
	public List<BeSectionStepJob> findUnFinishList(String sectionId) {
		BeSectionStepJob record = new BeSectionStepJob();
		record.setSectionId(sectionId);
		return findUnFinishList(record);
	}

	@Override
	public List<BeSectionStepJob> findUnFinishList(BeSectionStepJob record) {
		record.setIsFinish(Constants.IS_FINISH);
		record.setIsAdvanceExecute(Constants.IS_ADVANCE_EXECUTE);
		return beSectionStepJobMapper.selectUnFinishList(record);
	}


	/**
	 * 评审过程调用事件 sectionStepId: stage:0，环节未评审之前触发，1:环节评审完成之后触发,2:执行中
	 *
	 * @throws Exception
	 */
	@Transactional
	@Override
	public void callSectionJob(String sectionStepId, String submitCode, StepStage stage, String expertId,
							   String layoutCode, String isFinish, Integer jobState) throws Exception {
		// 多线程执行任务
		Object object = null;
		synchronized (this) {
			if (sectionStepMap.get(sectionStepId) == null) {
				sectionStepMap.put(sectionStepId, new Object());
			}
			object = sectionStepMap.get(sectionStepId);
		}
		synchronized (object) {
			BeSectionStepJob param = new BeSectionStepJob();
			param.setSectionStepId(sectionStepId);
			param.setIsFinish(isFinish);
			param.setIsAdvanceExecute(Constants.STATE_Y);
			param.setJobState(jobState);

			// 获取未完成的任务列表
			for (BeSectionStepJob beSectionStepJob : beSectionStepJobMapper.selectUnFinishList(param)) {
				try {
					BeSectionStep beSectionStep = beSectionStepMapper
							.selectByPrimaryKey(beSectionStepJob.getSectionStepId());

					if (beSectionStep != null) {
						param = new BeSectionStepJob();
						param.setSectionId(beSectionStep.getSectionId());
						param.setStage(stage.getCode());
						param.setIsFinish(isFinish);
						param.setIsAdvanceExecute(Constants.STATE_Y);
						param.setJobState(jobState);
						executeJob(expertId, layoutCode, stage, submitCode, beSectionStepJob, null, false);
					}
				}catch (Exception e) {
					log.error(e.getMessage(),e);
				}

			}
		}
	}
	public void executeChildJob(String expertId, StepStage stage, String submitCode,
								BeSectionStepJob beSectionStepJob, Map<String, Object> extendMap, boolean isConfirm) throws Exception {
		if (!StringUtils.isEmpty(beSectionStepJob.getJobClass())) {
			try {
				long startTime = System.currentTimeMillis();
				log.info("开始执行任务:" + beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + ",参数:"+ beSectionStepJob.getJobContent());
				Object instanceObject = Class.forName(beSectionStepJob.getJobClass()).newInstance();
				Boolean result = false;
				if (instanceObject instanceof StepJobJdbcFactory) {
					StepJobJdbcFactory stepQueueFactory = (StepJobJdbcFactory) instanceObject;
					stepQueueFactory.setJdbcTemplateService(jdbcTemplateService);
					result = stepQueueFactory.execute(beSectionStepJob, submitCode, expertId, beSectionStepJob.getLayoutCode());

				} else if (instanceObject instanceof StepJobFactory) {
					StepJobFactory stepJobFactory = (StepJobFactory) instanceObject;
					stepJobFactory.setJdbcTemplateService(jdbcTemplateService);
					result = stepJobFactory.execute(beSectionStepJob, submitCode, expertId, beSectionStepJob.getLayoutCode(), extendMap);
				}
				//if (!result) {
				log.info(beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + "运行结果为:"+result);
				//throw new BizException(beSectionStepJob.getJobName() + "任务计算失败");
				//}

				// 运行次数
				beSectionStepJob.setFinishCount(
						beSectionStepJob.getFinishCount() == null ? 1 : beSectionStepJob.getFinishCount() + 1);
				// 执行中和提交前阶段不受运行次数限制.job_count=0时候不受次数限制
				if (!StepStage.Between.getCode().equals(stage.getCode()) && !StepStage.Submit.getCode().equals(stage.getCode())) {
//					if (beSectionStepJob.getJobCount() != null
//							&& beSectionStepJob.getJobCount().intValue()<=beSectionStepJob.getFinishCount().intValue()) {
					beSectionStepJob.setIsFinish("1");
					beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
//					}
				}
				// 更新时间
				beSectionStepJob.setUpdateTime(new Date());
				beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
				log.info("运行时长:" + (System.currentTimeMillis() - startTime) / 1000 + "秒");
				executeCheckJob(beSectionStepJob, submitCode, expertId, beSectionStepJob.getLayoutCode(), isConfirm);
			} catch (Exception e) {
				log.info("执行任务异常:" + beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + ":"
						+ beSectionStepJob.getJobContent(),e);
				throw e;
			}
		}
	}

	public void executeJob(String expertId, String layoutCode, StepStage stage, String submitCode,
						   BeSectionStepJob beSectionStepJob, Map<String, Object> extendMap) throws Exception {
		executeJob(expertId, layoutCode, stage, submitCode, beSectionStepJob, extendMap, false);
	}
	/**
	 * 执行任务 @param @param sectionId @param @param sectionStepId @param @param
	 * expertId @param @param layoutCode @param @param stage @param @param
	 * submitCode @param @param beSectionStepJob 参数 @return void 返回类型 @throws
	 *
	 * @throws Exception
	 */
	public void executeJob(String expertId, String layoutCode, StepStage stage, String submitCode,
						   BeSectionStepJob beSectionStepJob, Map<String, Object> extendMap, boolean isConfirm) throws Exception {
		if (!StringUtils.isEmpty(beSectionStepJob.getJobClass())) {
			try {
				long startTime = System.currentTimeMillis();
				log.info("开始执行任务:" + beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + ",参数:"+ beSectionStepJob.getJobContent());
				Object instanceObject = Class.forName(beSectionStepJob.getJobClass()).newInstance();
				Boolean result = false;
				if (instanceObject instanceof StepJobJdbcFactory) {
					StepJobJdbcFactory stepQueueFactory = (StepJobJdbcFactory) instanceObject;
					stepQueueFactory.setJdbcTemplateService(jdbcTemplateService);
					result = stepQueueFactory.execute(beSectionStepJob, submitCode, expertId, layoutCode);

				} else if (instanceObject instanceof StepJobFactory) {
					StepJobFactory stepJobFactory = (StepJobFactory) instanceObject;
					stepJobFactory.setJdbcTemplateService(jdbcTemplateService);
					result = stepJobFactory.execute(beSectionStepJob, submitCode, expertId, layoutCode, extendMap);
				}
				//if (!result) {
				log.info(beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + "运行结果为:"+result);
				//throw new BizException(beSectionStepJob.getJobName() + "任务计算失败");
				//}

				// 运行次数
				beSectionStepJob.setFinishCount(
						beSectionStepJob.getFinishCount() == null ? 1 : beSectionStepJob.getFinishCount() + 1);
				// 执行中和提交前阶段不受运行次数限制.job_count=0时候不受次数限制
				if (!StepStage.Between.getCode().equals(stage.getCode()) && !StepStage.Submit.getCode().equals(stage.getCode())) {
//					if (beSectionStepJob.getJobCount() != null
//							&& beSectionStepJob.getJobCount().intValue()<=beSectionStepJob.getFinishCount().intValue()) {
					beSectionStepJob.setIsFinish("1");
					beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
//					}
				}
				// 更新时间
				beSectionStepJob.setUpdateTime(new Date());
				beSectionStepJobMapper.updateByPrimaryKey(beSectionStepJob);
				log.info("运行时长:" + (System.currentTimeMillis() - startTime) / 1000 + "秒");
				executeCheckJob(beSectionStepJob, submitCode, expertId, layoutCode, isConfirm);
			} catch (Exception e) {
				log.info("执行任务异常:" + beSectionStepJob.getJobName() + ":" + beSectionStepJob.getJobClass() + ":"
						+ beSectionStepJob.getJobContent(),e);
				throw e;
			}
		}
	}

	@Override
	@Transactional
	public void callStepUnionJob(BeSectionStep beSectionStep, String submitCode, String expertId, String layoutCode,
								 StepStage stage) throws Exception {
		this.callStepUnionJob(beSectionStep, submitCode, expertId, layoutCode, stage, false);
	}


	@Override
	@Transactional
	public void callStepUnionJob(BeSectionStep beSectionStep, String submitCode, String expertId, String layoutCode,
								 StepStage stage, boolean isConfirm) throws Exception {
		//左侧菜单栏不需要执行子环节任务
		if(LayoutCode.Left.name().equals(layoutCode)) {
			return;
		}
		Object object = null;
		synchronized (this) {
			if (sectionStepMap.get(beSectionStep.getSeqId()) == null) {
				sectionStepMap.put(beSectionStep.getSeqId(), System.currentTimeMillis());
			}
			object = sectionStepMap.get(beSectionStep.getSeqId());
		}
		log.info(beSectionStep.getStepName()+",开始执行关联子环节,环节代码:"+beSectionStep.getStepCode());

		synchronized (object) {
			// 级别
			Integer sortNum = 0;
			// 定义key排序的map
			Map<Integer, List<BeSectionStepJob>> childSectionStepJobMap = Maps.newTreeMap(new Comparator<Integer>() {
				@Override
				public int compare(Integer s1, Integer s2) {
					return s2.compareTo(s1); // 从大到小排序
				}
			});
			Map<String, Object> paramMap = Maps.newHashMap();
			for (BeSectionParameter beSectionParameter : beSectionParameterService
					.selectList(beSectionStep.getSectionId())) {
				paramMap.put("$PARAM_" + beSectionParameter.getParamId(), beSectionParameter.getParamValue());
			}
			if (beSectionStep != null) {
				BeSectionStepJob param = new BeSectionStepJob();
				param.setSectionStepId(beSectionStep.getSeqId());
				param.setStage(stage.getCode());
				param.setSectionId(beSectionStep.getSectionId());
				param.setIsFinish("0");
				// 如果存在关联子节点任务，则先执行子节点任务
				param.setUnionChildren("1");
				// 获取第0级任务
				sortNum = 0;
				childSectionStepJobMap.put(sortNum, Arrays.asList(new BeSectionStepJob[] {}));
				// 第1级任务
				for (BeSectionStep sectionStep : beSectionStepMapper
						.getChildSectionStepList(beSectionStep.getSectionId(), beSectionStep.getStepCode())) {
					param.setSectionStepId(sectionStep.getSeqId());
					unionSectionStepJobList = childSectionStepJobMap.get(sortNum + 1);
					if (unionSectionStepJobList == null) {
						unionSectionStepJobList = new ArrayList<BeSectionStepJob>();
					}
					unionSectionStepJobList.addAll(beSectionStepJobMapper.selectUnFinishList(param));
					childSectionStepJobMap.put(sortNum + 1, unionSectionStepJobList);
					// 获取第二级任务
					selectChildList(childSectionStepJobMap, sortNum + 2, sectionStep.getStepCode(), param);
				}
				log.info(beSectionStep.getStepName()+"当前环节所有子环节:" + childSectionStepJobMap);
				// 按照倒叙从最高级执行到最低级
				for (Entry<Integer, List<BeSectionStepJob>> entry : childSectionStepJobMap.entrySet()) {
					if (entry.getValue() != null) {
						for (BeSectionStepJob sectionStepJob : entry.getValue()) {
							executeChildJob(expertId, stage, submitCode, sectionStepJob, paramMap, isConfirm);
						}
					}

				}

			}
		}
	}
	/**
	 * added by daizhifeng
	 */
	@Override
	public int findUnFinishCnt(String sectionStepId) {
		return beSectionStepJobMapper.findUnFinishCnt(sectionStepId);
	}

	@Override
	public int updateStepJobBySectionId(String sectionId) throws Exception {
		BeSectionStepJob beSectionStepJob = new BeSectionStepJob();
		//更新需要提前执行任务的状态为可以执行
		beSectionStepJob.setSectionId(sectionId);
		beSectionStepJob.setIsAdvanceExecute(Constants.STATE_Y);
		//2表示可以执行（用于提前执行的任务）
		beSectionStepJob.setJobState(Constants.TWO);
		beSectionStepJob.setUpdateTime(DateUtil.now());
		//更新标段环节任务状态为可以执行
		return beSectionStepJobMapper.updateStepJobBySectionId(beSectionStepJob);
	}

	private void executeCheckJob(BeSectionStepJob beSectionStepJob, String submitCode, String expertId, String layoutCode, boolean isConfirm) throws Exception {
		CheckMsgTypeEnum checkMsgType = beSectionStepJob.getCheckMsgTypeEnum();
		if (CheckMsgTypeEnum.None.equals(checkMsgType)) {
			return;
		}

		try {
			String sectionStepId = beSectionStepJob.getSectionStepId();
			String sectionId = beSectionStepJob.getSectionId();
			log.info(String.format("Job检查开始: sectionId:%s  expertId:%s sectionStepId: %s", sectionId, sectionStepId, expertId));
			List<CheckJob> checkJobs = CheckJob.parseCheckJob(beSectionStepJob.getCheckJobClass());

			for (CheckJob checkJob: checkJobs) {
				checkJob.init(sectionId, sectionStepId, submitCode, expertId, layoutCode, checkMsgType);
				log.info(String.format("Job检查开始: %s", checkJob.toString()));
				CheckJobBase checkJobBase = (CheckJobBase) Class.forName(checkJob.getCheckJobClz()).newInstance();
				checkJobBase.baseCheck(checkJob);
			}
			log.info(String.format("Job检查结束: sectionId:%s  expertId:%s sectionStepId: %s", sectionId, sectionStepId, expertId));
		} catch (CheckException e) {
//			if (!CheckMsgTypeEnum.Alert.equals(checkMsgType)) {
				throw e;
//			}
		} catch (Exception e) {
			throw e;
		}
		log.info("Job检查结束");
	}

	@Override
	public void callStepJob(CallStepJobVi callStepJobVi, StepStage stepStage) throws Exception{
		BeSectionStep beSectionStep = beSectionStepMapper.selectByPrimaryKey(callStepJobVi.getBeSectionStepId());
		String submitCode = callStepJobVi.getSubmitCode();
		String expertId = callStepJobVi.getExpertId();
		String layoutCode = callStepJobVi.getLayoutCode();
		Boolean isConfirm = callStepJobVi.isConfirm();
		log.info("其他专家都已经提交完成，开始执行job任务，标段id[" + beSectionStep.getSectionId() + "]，环节id[" + beSectionStep.getSeqId() + "],专家id[" + expertId + "]");
		//执行该环节所有专家完成之后的事件
		callStepUnionJob(beSectionStep, submitCode, expertId, layoutCode, stepStage, isConfirm);
		callStepJob(beSectionStep, submitCode, stepStage, expertId, layoutCode, isConfirm);
		log.info("所有专家提交之后的job任务执行完成。。。");
	}

	@Override
	public void callStepJobBySumbit(CallStepJobVi callStepJobVi) throws Exception {
		String expertId = callStepJobVi.getExpertId();
		String submitCode = callStepJobVi.getSubmitCode();
		BeSectionStep beSectionStep = beSectionStepMapper.selectByPrimaryKey(callStepJobVi.getBeSectionStepId());
		String isFinish = Constants.STR_YES;
		String layoutCode = callStepJobVi.getLayoutCode();
		boolean isConfirm = callStepJobVi.isConfirm();
		//执行该环节所有专家完成之后的事件
		callStepJob(callStepJobVi, StepStage.Submit);
		try {
			//其他专家都已经提交完成
			if (beSectionExpertProgressService.isOtherExpertFinished(beSectionStep.getSeqId(), expertId)) {
				AutoVoteJobVi autoVoteJobVi = new AutoVoteJobVi(beSectionStep.getSectionId(), beSectionStep.getSeqId(), layoutCode, submitCode, expertId, isFinish, isConfirm);
				// 自动表决判断，Before 发起后，不在继续下面操作
				beAutoVoteConfigService.launchAutoVote(VoteLocationEnum.Before, autoVoteJobVi);
				callStepJob(callStepJobVi, StepStage.After);
				// 自动发起表决，后面的不受影响
				beAutoVoteConfigService.launchAutoVote(VoteLocationEnum.After, autoVoteJobVi);
			} else {
				log.info("其他专家未提交完成，不执行job任务，标段id[" + beSectionStep.getSectionId() + "]，环节id[" + beSectionStep.getSeqId() + "],专家id[" + expertId + "]");
			}

		} catch (CheckException e) {
			// 检查不通过把 list
			//resetUnFinishState(e.getResetUnFinishStateList(), beSectionStep);
			// 如果websocket状态不无法区分，可能需要增加个状态值
		}

		//更新当前所有子节点环节完成状态
		BeSectionExpertProgress beSectionExpertProgress = beSectionExpertProgressService
				.selectByKey(beSectionStep.getSeqId(), expertId);
		beSectionExpertProgress.setIsFinish(isFinish);
		beSectionExpertProgressService.update(beSectionExpertProgress);
		for (BeSectionStep sectionStep : beSectionStepMapper.getAllChildSectionStep(beSectionStep.getSectionId(),
				beSectionStep.getStepCode())) {
			beSectionExpertProgress = beSectionExpertProgressService.selectByKey(sectionStep.getSeqId(), expertId);
			beSectionExpertProgress.setIsFinish(isFinish);
			beSectionExpertProgressService.update(beSectionExpertProgress);
		}
		//更新父环节完成状态
		updateParentFinishState(beSectionStep.getSectionId(), beSectionStep.getStepCode());



	}

	@Override
	public void resetUnFinishStateAndProgress(List<String> experts, String beSectionStepId) throws Exception {
		_resetUnFinishStateAndProgress(experts, beSectionStepId, true);
	}

	@Override
	public void resetUnFinishJobState(List<String> experts, String beSectionStepId) throws Exception {
		_resetUnFinishStateAndProgress(experts, beSectionStepId, false);
	}

	private void _resetUnFinishStateAndProgress(List<String> experts, String beSectionStepId, boolean resetProgress) throws Exception {
		BeSectionStep beSectionStep = beSectionStepMapper.selectByPrimaryKey(beSectionStepId);
		List<BeSectionStep> childSectionStep= beSectionStepMapper.getAllChildSectionStep(beSectionStep.getSectionId(), beSectionStep.getStepCode());
		for (String expertId : experts) {
			//更新当前所有子节点环节完成状态
			BeSectionExpertProgress beSectionExpertProgress = beSectionExpertProgressService
					.selectByKey(beSectionStep.getSeqId(), expertId);
			if (resetProgress) {
				beSectionExpertProgress.setIsFinish(Constants.IS_FINISH);
				beSectionExpertProgressService.update(beSectionExpertProgress);
			}
			//更新任务状态
			updateStepJobByStepId(beSectionStepId, Constants.IS_FINISH);
			// 更新子任务
			for (BeSectionStep sectionStep : childSectionStep) {
				beSectionExpertProgress = beSectionExpertProgressService.selectByKey(sectionStep.getSeqId(), expertId);
				beSectionExpertProgress.setIsFinish(Constants.IS_FINISH);
				beSectionExpertProgressService.update(beSectionExpertProgress);
				//更新任务状态
				resetSubmitStepJobByStepId(sectionStep.getSeqId(), Constants.IS_FINISH);
			}
		}
		BeSectionInfo sectionInfo = new BeSectionInfo();
		sectionInfo.setSeqId(beSectionStep.getSectionId());
		//评审中
		sectionInfo.setReviewState(ReviewStateEnum.Reviewing.code);
		beSectionInfoMapper.updateByPrimaryKeySelective(sectionInfo);
	}

	/**
	 * 更新父环节完成状态
	 * @param sectionId
	 * @param stepCode
	 * @throws Exception
	 */
	private void updateParentFinishState(String sectionId, String stepCode) throws Exception {
		//查询是否有父环节
		BeSectionStep parentSectionStep = beSectionStepMapper.getParentSectionStep(sectionId, stepCode);
		//父环节不为空
		if(parentSectionStep != null) {
			//根据父环节节点获取最后一个子环节节点
			BeSectionStep lastSectionStep = beSectionStepMapper.getLastSectionStep(sectionId, parentSectionStep.getStepCode());
			//判断最后一个环节是否已完成
			if(lastSectionStep != null) {
				if (beSectionExpertProgressService.getFinishStatus(lastSectionStep.getSeqId())) {
					//更新父环节完成状态
					for (BeSectionExpertProgress beSectionExpertProgress : beSectionExpertProgressMapper.selectListByStepId(parentSectionStep.getSeqId())) {
						beSectionExpertProgress.setIsFinish(Constants.STR_YES);
						beSectionExpertProgress.setUpdateTime(new Date());
						beSectionExpertProgressMapper.updateByPrimaryKey(beSectionExpertProgress);
					}
				}
			}
		}
	}


}
